package math2;

/**
 * Lagrange basis function on 10-node tetrahedra
 * 
 * @author hbui
 * 
 */
public class LagrangeFBOnTet10 extends PolynomialBasisOnRnToR {

	public LagrangeFBOnTet10() {

		addBasisFunction(
		/*
		 * N1
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... xi) {
				return (-1 + 2 * (1 - xi[0] - xi[1] - xi[2])) * (1 - xi[0] - xi[1] - xi[2]);
			}

			@Override
			public double[] gradientAt(double... xi) {
				return new double[] { 1 - 4 * (1 - xi[0] - xi[1] - xi[2]),
						1 - 4 * (1 - xi[0] - xi[1] - xi[2]), 1 - 4 * (1 - xi[0] - xi[1] - xi[2]) };
			}
		},
		/*
		 * N2
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... xi) {
				return xi[0] * (-1 + 2 * xi[0]);
			}

			@Override
			public double[] gradientAt(double... xi) {
				return new double[] { -1 + 4 * xi[0], 0, 0 };
			}
		},
		/*
		 * N3
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... xi) {
				return xi[1] * (-1 + 2 * xi[1]);
			}

			@Override
			public double[] gradientAt(double... xi) {
				return new double[] { 0, -1 + 4 * xi[1], 0 };
			}
		},
		/*
		 * N4
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... xi) {
				return xi[2] * (-1 + 2 * xi[2]);
			}

			@Override
			public double[] gradientAt(double... xi) {
				return new double[] { 0, 0, -1 + 4 * xi[2] };
			}
		},
		/*
		 * N5
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... xi) {
				return 4 * xi[0] * (1 - xi[0] - xi[1] - xi[2]);
			}

			@Override
			public double[] gradientAt(double... xi) {
				return new double[] { -4 * xi[0] + 4 * (1 - xi[0] - xi[1] - xi[2]), -4 * xi[0],
						-4 * xi[0] };
			}
		},
		/*
		 * N6
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... xi) {
				return 4 * xi[0] * xi[1];
			}

			@Override
			public double[] gradientAt(double... xi) {
				return new double[] { 4 * xi[1], 4 * xi[0], 0 };
			}
		},
		/*
		 * N7
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... xi) {
				return 4 * xi[1] * (1 - xi[0] - xi[1] - xi[2]);
			}

			@Override
			public double[] gradientAt(double... xi) {
				return new double[] { -4 * xi[1], -4 * xi[1] + 4 * (1 - xi[0] - xi[1] - xi[2]),
						-4 * xi[1] };
			}
		},
		/*
		 * N8
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... xi) {
				return 4 * (1 - xi[0] - xi[1] - xi[2]) * xi[2];
			}

			@Override
			public double[] gradientAt(double... xi) {
				return new double[] { -4 * xi[2], -4 * xi[2],
						4 * (1 - xi[0] - xi[1] - xi[2]) - 4 * xi[2] };
			}
		},
		/*
		 * N9
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... xi) {
				return 4 * xi[0] * xi[2];
			}

			@Override
			public double[] gradientAt(double... xi) {
				return new double[] { 4 * xi[2], 0, 4 * xi[0] };
			}
		},
		/*
		 * N10
		 */
		new FunctionRnToR() {

			@Override
			public double valueAt(double... xi) {
				return 4 * xi[1] * xi[2];
			}

			@Override
			public double[] gradientAt(double... xi) {
				return new double[] { 0, 4 * xi[2], 4 * xi[1] };
			}
		});
	}

	@Override
	public int getP() {
		return 2;
	}

	@Override
	public void setP(int p) {
	}

	@Override
	public Object clone() {
		return new LagrangeFBOnTet10();
	}

}
